package org.hackystat.sdsa.analyzer.model.activity.refactoring;

import java.util.Map;
import java.util.logging.Logger;

import jess.Fact;
import jess.JessException;
import jess.RU;
import jess.Rete;
import jess.Value;

import org.hackystat.sdsa.analyzer.control.SensorDataUtil;
import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData;

/**
 * Defines refactor action with two operands or subjects respectively.
 * 
 * @author Hongbing Kou
 */
public final class BinaryRefactorActivity extends RefactorActivity {
  /** From refactor subject. */
  private String fromSubject;
  /** To refactor subject. */
  private String toSubject;
  
  /** From unit name. */
  public static final String FROM_UNIT_NAME = "from-unit-name";
  /** To unit name. */
  public static final String TO_UNIT_NAME = "to-unit-name";
 
  /**
   * Empty refactor.
   * 
   * @param op RefactorOperator.
   * @param st SubjectType.
   */
  public BinaryRefactorActivity(RefactorOperator op, RefactorSubjectType st) {
    super(op, st);
  }

  
  /**
   * Constructs an binaryrefactor action.
   * 
   * @param sensorData Sensor data.
   * @param logger Logger.
   */
  public BinaryRefactorActivity(SensorData sensorData, Logger logger) {
    super(sensorData, logger);
    
    Map<String, String> propMap = SensorDataUtil.propMap(sensorData);
    this.fromSubject = propMap.get(FROM_UNIT_NAME);
    this.toSubject = propMap.get(TO_UNIT_NAME);
 }

  /**
   * Sets the original subject.
   * 
   * @param fromSubject From subject. 
   */
  public void setFromSubject(String fromSubject) {
    this.fromSubject = fromSubject;
  }

  /**
   * Sets the destined subject.
   * 
   * @param toSubject To subject.
   */
  public void setToSubject(String toSubject) {
    this.toSubject = toSubject;    
  }

  /**
   * Gets from subject of the refactoring.
   * 
   * @return From refactor subject.
   */
  public String getFromSubject() {
    return this.fromSubject;
  }

  /**
   * Gets to subject of the refactoring.
   * 
   * @return To subject.
   */
  public String getToSubject() {
    return this.toSubject;
  }

  /**
   * Makes Jess facts in the given Jess rete engine.
   * 
   * @param index Index of action in episode.
   * @param engine Jess rete engine.
   * @throws JessException If error while constructing jess action.
   * @return Jess fact of this action.
   */
  @Override public Fact assertActivity(int index, Rete engine) throws JessException  {
    Fact f = new Fact("BinaryRefactorActivity", engine);
    f.setSlotValue(INDEX_SLOT, new Value(index, RU.INTEGER));
    String file = super.extractFileName(super.getResourceUri());
    f.setSlotValue(FILE_SLOT, new Value(file, RU.STRING));
    f.setSlotValue("operation", new Value(this.getOperator().getName(), RU.STRING));
    f.setSlotValue("type", new Value(this.getSubjectType().getName(), RU.STRING));
    f.setSlotValue("from", new Value(this.getFromSubject(), RU.STRING));
    f.setSlotValue("to", new Value(this.getToSubject(), RU.STRING));
    
    Fact assertedFact = engine.assertFact(f);
    return assertedFact;
  }  
  
  /**
   * Gets binary refactor string.
   * 
   * @return Binary refactor string.
   */
  @Override public String toString() {
    return super.toString() + " {" + this.fromSubject + " -> " + this.toSubject + "}";
  }

  /** 
   * Get the representation of this activity. 
   * 
   * @return String representation of this activity.
   */
  @Override public String getRepresentation() {
    StringBuffer buf = new StringBuffer();
    
    buf.append(this.getFromSubject());
    buf.append(" --> ");
    buf.append(this.getToSubject());

    return buf.toString();
  }
}
